package com.octoplay.player;

import android.app.Activity;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.net.Uri;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.RelativeLayout;

public class AndroidMediaPlayer extends BaseMediaPlayer {

	public static String LOGTAG = "AndroidMediaPlayer";
	private MediaPlayer mMediaPlayer;
    private SurfaceView mPreview;
    private SurfaceHolder holder;
	private int mVideoHeight;
	private int mVideoWidth;
	//private int mSurfaceWidth;
	//private int mSurfaceHeight;
	
	public AndroidMediaPlayer(){
		
	}
	
	public AndroidMediaPlayer (Activity activity, final PlayerListener listener){
    	this.mActivity = activity;
    	this.listener = listener;
    	
    	STATUS = STATUS_IDLE;
    	mPreview = new SurfaceView(activity);
		mPreview.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				AndroidMediaPlayer.this.listener.onPlayerClicked(AndroidMediaPlayer.this);
			}
		});
		
		mPreview.setOnKeyListener(new OnKeyListener() {
			
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if(keyCode == KeyEvent.KEYCODE_BACK){
					AndroidMediaPlayer.this.listener.onKey(v, keyCode, event);
				}
				return false;
			}
		});
		mMediaPlayer = new MediaPlayer();
		holder = mPreview.getHolder();
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		holder.addCallback(new Callback() {
			
			@Override
			public void surfaceDestroyed(SurfaceHolder holder) {
				Log.v(LOGTAG, "surfaceDestroyed");
			}
			@Override
			public void surfaceCreated(SurfaceHolder holder) {
				Log.v(LOGTAG, "surfaceCreated");
				mMediaPlayer.setDisplay(holder);
			}
			@Override
			public void surfaceChanged(SurfaceHolder holder, int format, int width,
					int height) {
				Log.v(LOGTAG, "surfaceChanged");
				fixAspectRatio();
			}
		});
		mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
			@Override
			public void onCompletion(MediaPlayer mp) {
				Log.v(LOGTAG, "onCompletion called");
				STATUS = STATUS_PLAYBACKCOMPLETED;
				listener.onPlaybackComplete(AndroidMediaPlayer.this);
			}
		});
		mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
			@Override
			public void onPrepared(MediaPlayer mp) {
				Log.v(LOGTAG, "onPrepared called");
				STATUS = STATUS_PREPARED;
		        listener.onPrepared(AndroidMediaPlayer.this);
		    }
		});
		mMediaPlayer
				.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
					@Override
					public void onVideoSizeChanged(MediaPlayer mp, int width,
							int height) {
						Log.v(LOGTAG, "onVideoSizeChanged called");
						AndroidMediaPlayer.this.mVideoHeight= height;
						AndroidMediaPlayer.this.mVideoWidth = width;
						fixAspectRatio();
					}
				});
		mMediaPlayer.setOnSeekCompleteListener(new OnSeekCompleteListener() {
			@Override
			public void onSeekComplete(MediaPlayer mp) {
				Log.v(LOGTAG, "setOnSeekCompleteListener called");
				listener.onNativeSeekComplete(AndroidMediaPlayer.this);
				STATUS = STATUS_STARTED;
			}
		});
		mMediaPlayer.setOnErrorListener(new OnErrorListener() {
			@Override
			public boolean onError(MediaPlayer mp, int what, int extra) {
				STATUS = STATUS_ERROR;
				listener.onPlayerError(AndroidMediaPlayer.this, what+":"+extra);
				return false;
			}
		});
		mMediaPlayer.setScreenOnWhilePlaying(true);
	}
	protected void fixAspectRatio(){

		if(mVideoWidth == 0 || mVideoHeight == 0)
			return;
		
		int height, width;
		
		DisplayMetrics displaymetrics = new DisplayMetrics();
		mActivity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		
		if(mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
			height = displaymetrics.heightPixels;
			width = displaymetrics.widthPixels;
		}
		else{
			height = (int) (0.56 * displaymetrics.widthPixels);
			width = displaymetrics.widthPixels;
		}
		int verticalMargin, horizontalMargin;
		float aspectRatio = (float) mVideoWidth / mVideoHeight;
		float screenRatio = (float) width / height;
		
		RelativeLayout.LayoutParams vLayout;
		
		if (screenRatio <= aspectRatio) {
			vLayout = new RelativeLayout.LayoutParams(width, (int) (width/aspectRatio));
			horizontalMargin = 0;
			verticalMargin =  (int) (height - ((float)width/aspectRatio));
		
		} else {
			vLayout = new RelativeLayout.LayoutParams((int)(height*aspectRatio), height);
			verticalMargin = 0;
			horizontalMargin =  (int) (width - ((float)height*aspectRatio));
			
		}
		vLayout.setMargins(horizontalMargin/2, verticalMargin/2, 0, 0); 
		mPreview.setLayoutParams(vLayout); 
	}
	
	/*protected void adjustMargin() {
		
		
		
		
		int verticalMargin, horizontalMargin;
		float aspectRatio = (float) mVideoWidth / mVideoHeight;
		float screenRatio = (float) mSurfaceWidth / mSurfaceHeight;
		
		RelativeLayout.LayoutParams vLayout;// = (RelativeLayout.LayoutParams) mPreview.getLayoutParams();
		
		if(mVideoWidth > 0 && mVideoHeight > 0){
		
		if (screenRatio <= aspectRatio) {
			horizontalMargin = 0;
			verticalMargin =  (int) (mSurfaceHeight - ((float)mSurfaceWidth/aspectRatio));
			vLayout = new RelativeLayout.LayoutParams(mSurfaceWidth, (int) (mSurfaceWidth/aspectRatio));
		} else {
			verticalMargin = 0;
			horizontalMargin =  (int) (mSurfaceWidth - ((float)mSurfaceHeight*aspectRatio));
			vLayout = new RelativeLayout.LayoutParams((int)(mSurfaceHeight*aspectRatio), mSurfaceHeight);
		}
		vLayout.setMargins(horizontalMargin/2, verticalMargin/2, 0, 0); 
		mPreview.setLayoutParams(vLayout); 
		}
		
		Log.d(LOGTAG, "Dimensions 2: " + getView().getWidth()
				+ ":" + getView().getHeight());
		
	}*/
	@Override
	public void requestNativeSeek(int seekTo) {
		Log.v(LOGTAG, "nativeSeekTo: " + seekTo + "/"+ mMediaPlayer.getDuration() );
		mMediaPlayer.seekTo(seekTo);
	}
	@Override
	public void pause() {
		mMediaPlayer.pause();
		STATUS = STATUS_PAUSED;
	}
	public void start() {
		play();
	}
	@Override
	public void play() {
		mMediaPlayer.start();
		Log.d(LOGTAG, "STATUS: STATUS_STARTED");
		STATUS = STATUS_STARTED;
	}
	@Override
	public void stop() {
		mMediaPlayer.stop();
		STATUS = STATUS_STOPPED;
		
	}
	@Override
	public int getCurrentPosition() {
		
		if (mMediaPlayer != null && STATUS == STATUS_STARTED || STATUS == STATUS_PAUSED )
			return mMediaPlayer.getCurrentPosition();
		else
			return 0;
	}
	@Override
	public int getDuration() {
		if(STATUS == STATUS_STARTED && STATUS == STATUS_PAUSED)
			return mMediaPlayer.getDuration();
		else
			return 0;
	}
	@Override
	public void release() {
		STATUS = STATUS_IDLE;
		mMediaPlayer.release();
	}

	@Override
	public void reset() {
		STATUS = STATUS_IDLE;
		mMediaPlayer.reset();
	}
	@Override
	public void prepare() {
			try {
				mMediaPlayer.setDataSource(mActivity, playUrl);
				mMediaPlayer.prepareAsync();
			} catch (Exception e) {
				listener.onPlayerError(this, "Preparing failed");
				STATUS = STATUS_ERROR;
			}
	}
	@Override
	public boolean isPrepared() {
		
		return STATUS >= STATUS_PREPARED?true:false; 
	}
	@Override
	public boolean isPlaying() {
		
		return STATUS == STATUS_STARTED?true:false;
	}
	@Override
	public boolean isPaused() {
		
		return STATUS == STATUS_PAUSED?true:false;
	}
	@Override
	public View getView() {
		return mPreview;
	}
	@Override
	public void setDataSource(Uri url) {
		playUrl = url;
		STATUS = STATUS_INITIALIZED;
	}
}